// Chrome 55+可以使用
// 要求node >= 7
// 启用标志harmony:  node --harmony async.js
async function myFirstAsyncFunction() {
  try {
    // 当函数执行的时候，一旦遇到await就会先返回，等到异步操作完成，再接着执行函数体内后面的语句。
		// await命令后面是一个 Promise 对象。如果不是，会被转成一个立即resolve的 Promise 对象。
		let p = await timeout('hello async') 
		console.log(await p)
		// await 会解析Promise对象, 效果同下
		//console.log(Promise.resolve(p))

		return 'in return'
  }
  catch (rejectedValue) {
    // …
  }
}


// async函数永远返回Promise对象
// return的值存在于Promise对象中, 需要调用then才能获得
myFirstAsyncFunction().then(data => console.log(data))

console.log('顺序执行的语句')

// await只能在async函数中使用
// When you await a promise, the function is paused in a non-blocking way until the promise settles. If the promise fulfills, you get the value back. If the promise rejects, the rejected value is thrown.

module.exports = myFirstAsyncFunction

// 注意性能, 并行下载 (对函数内部而言, 流程是同步的)
async function logInOrder(urls) {
  // fetch all the URLs in parallel
	// 虽然map方法的参数是async函数，但它是并发执行的，因为只有async函数内部是继发执行，外部不受影响
  const textPromises = urls.map(async url => {
    const response = await fetch(url);
    return response.text();
  });

	// 显示时按顺序
  // log them in sequence 
  for (const textPromise of textPromises) {
    console.log(await textPromise);
  }
}

function timeout(msg) {
  return new Promise((resolve) => {
    setTimeout(resolve.bind(null, msg), 1000);
  });
}

function getFoo() {
  timeout('getFoo')
}

function getBar() {
  timeout('getBar')
}

// 以下是有区别的, 虽然有点又难懂
// getFoo与getBar顺序执行
(async function(){
  let foo1 = await getFoo();
  let bar1 = await getBar();
  
  // getFoo和getBar同时触发
  let fooPromise = getFoo();
  let barPromise = getBar();
  let foo2 = await fooPromise;
  let bar2 = await barPromise;
}())
